#include <xen/config.h>
#include <xen/errno.h>
+#include <xen/acpi.h>
#include <asm/apicdef.h>
#include <asm/amd-iommu.h>
#include <asm/hvm/svm/amd-iommu-proto.h>
-#include <asm/hvm/svm/amd-iommu-acpi.h>
+
+/* Some helper structures, particularly to deal with ranges. */
+
+struct acpi_ivhd_device_range {
+ struct acpi_ivrs_device4 start;
+ struct acpi_ivrs_device4 end;
+};
+
+struct acpi_ivhd_device_alias_range {
+ struct acpi_ivrs_device8a alias;
+ struct acpi_ivrs_device4 end;
+};
+
+struct acpi_ivhd_device_extended_range {
+ struct acpi_ivrs_device8b extended;
+ struct acpi_ivrs_device4 end;
+};
+
+union acpi_ivhd_device {
+ struct acpi_ivrs_de_header header;
+ struct acpi_ivrs_device4 select;
+ struct acpi_ivhd_device_range range;
+ struct acpi_ivrs_device8a alias;
+ struct acpi_ivhd_device_alias_range alias_range;
+ struct acpi_ivrs_device8b extended;
+ struct acpi_ivhd_device_extended_range extended_range;
+ struct acpi_ivrs_device8c special;
+};
static unsigned short __initdata last_bdf;
}
static int __init parse_ivmd_device_select(
- struct acpi_ivmd_block_header *ivmd_block,
+ const struct acpi_ivrs_memory *ivmd_block,
unsigned long base, unsigned long limit, u8 iw, u8 ir)
{
u16 bdf;
- bdf = ivmd_block->header.dev_id;
+ bdf = ivmd_block->header.device_id;
if ( bdf >= ivrs_bdf_entries )
{
AMD_IOMMU_DEBUG("IVMD Error: Invalid Dev_Id 0x%x\n", bdf);
}
static int __init parse_ivmd_device_range(
- struct acpi_ivmd_block_header *ivmd_block,
+ const struct acpi_ivrs_memory *ivmd_block,
unsigned long base, unsigned long limit, u8 iw, u8 ir)
{
u16 first_bdf, last_bdf, bdf;
int error;
- first_bdf = ivmd_block->header.dev_id;
+ first_bdf = ivmd_block->header.device_id;
if ( first_bdf >= ivrs_bdf_entries )
{
AMD_IOMMU_DEBUG("IVMD Error: "
return -ENODEV;
}
- last_bdf = ivmd_block->last_dev_id;
+ last_bdf = ivmd_block->aux_data;
if ( (last_bdf >= ivrs_bdf_entries) || (last_bdf <= first_bdf) )
{
AMD_IOMMU_DEBUG("IVMD Error: "
}
static int __init parse_ivmd_device_iommu(
- struct acpi_ivmd_block_header *ivmd_block,
+ const struct acpi_ivrs_memory *ivmd_block,
unsigned long base, unsigned long limit, u8 iw, u8 ir)
{
struct amd_iommu *iommu;
/* find target IOMMU */
- iommu = find_iommu_from_bdf_cap(ivmd_block->header.dev_id,
- ivmd_block->cap_offset);
+ iommu = find_iommu_from_bdf_cap(ivmd_block->header.device_id,
+ ivmd_block->aux_data);
if ( !iommu )
{
AMD_IOMMU_DEBUG("IVMD Error: No IOMMU for Dev_Id 0x%x Cap 0x%x\n",
- ivmd_block->header.dev_id, ivmd_block->cap_offset);
+ ivmd_block->header.device_id, ivmd_block->aux_data);
return -ENODEV;
}
iommu, base, limit, iw, ir);
}
-static int __init parse_ivmd_block(struct acpi_ivmd_block_header *ivmd_block)
+static int __init parse_ivmd_block(const struct acpi_ivrs_memory *ivmd_block)
{
unsigned long start_addr, mem_length, base, limit;
u8 iw, ir;
- if ( ivmd_block->header.length <
- sizeof(struct acpi_ivmd_block_header) )
+ if ( ivmd_block->header.length < sizeof(*ivmd_block) )
{
AMD_IOMMU_DEBUG("IVMD Error: Invalid Block Length!\n");
return -ENODEV;
}
- start_addr = (unsigned long)ivmd_block->start_addr;
- mem_length = (unsigned long)ivmd_block->mem_length;
+ start_addr = (unsigned long)ivmd_block->start_address;
+ mem_length = (unsigned long)ivmd_block->memory_length;
base = start_addr & PAGE_MASK;
limit = (start_addr + mem_length - 1) & PAGE_MASK;
AMD_IOMMU_DEBUG(" Start_Addr_Phys 0x%lx\n", start_addr);
AMD_IOMMU_DEBUG(" Mem_Length 0x%lx\n", mem_length);
- if ( get_field_from_byte(ivmd_block->header.flags,
- AMD_IOMMU_ACPI_EXCLUSION_RANGE_MASK,
- AMD_IOMMU_ACPI_EXCLUSION_RANGE_SHIFT) )
+ if ( ivmd_block->header.flags & ACPI_IVMD_EXCLUSION_RANGE )
iw = ir = IOMMU_CONTROL_ENABLED;
- else if ( get_field_from_byte(ivmd_block->header.flags,
- AMD_IOMMU_ACPI_UNITY_MAPPING_MASK,
- AMD_IOMMU_ACPI_UNITY_MAPPING_SHIFT) )
+ else if ( ivmd_block->header.flags & ACPI_IVMD_UNITY )
{
- iw = get_field_from_byte(ivmd_block->header.flags,
- AMD_IOMMU_ACPI_IW_PERMISSION_MASK,
- AMD_IOMMU_ACPI_IW_PERMISSION_SHIFT);
- ir = get_field_from_byte(ivmd_block->header.flags,
- AMD_IOMMU_ACPI_IR_PERMISSION_MASK,
- AMD_IOMMU_ACPI_IR_PERMISSION_SHIFT);
+ iw = ivmd_block->header.flags & ACPI_IVMD_READ ?
+ IOMMU_CONTROL_ENABLED : IOMMU_CONTROL_DISABLED;
+ ir = ivmd_block->header.flags & ACPI_IVMD_WRITE ?
+ IOMMU_CONTROL_ENABLED : IOMMU_CONTROL_DISABLED;
}
else
{
switch( ivmd_block->header.type )
{
- case AMD_IOMMU_ACPI_IVMD_ALL_TYPE:
+ case ACPI_IVRS_TYPE_MEMORY_ALL:
return register_exclusion_range_for_all_devices(
base, limit, iw, ir);
- case AMD_IOMMU_ACPI_IVMD_ONE_TYPE:
+ case ACPI_IVRS_TYPE_MEMORY_ONE:
return parse_ivmd_device_select(ivmd_block,
base, limit, iw, ir);
- case AMD_IOMMU_ACPI_IVMD_RANGE_TYPE:
+ case ACPI_IVRS_TYPE_MEMORY_RANGE:
return parse_ivmd_device_range(ivmd_block,
base, limit, iw, ir);
- case AMD_IOMMU_ACPI_IVMD_IOMMU_TYPE:
+ case ACPI_IVRS_TYPE_MEMORY_IOMMU:
return parse_ivmd_device_iommu(ivmd_block,
base, limit, iw, ir);
}
static u16 __init parse_ivhd_device_select(
- union acpi_ivhd_device *ivhd_device, struct amd_iommu *iommu)
+ const struct acpi_ivrs_device4 *select, struct amd_iommu *iommu)
{
u16 bdf;
- bdf = ivhd_device->header.dev_id;
+ bdf = select->header.id;
if ( bdf >= ivrs_bdf_entries )
{
AMD_IOMMU_DEBUG("IVHD Error: Invalid Device_Entry Dev_Id 0x%x\n", bdf);
return 0;
}
- add_ivrs_mapping_entry(bdf, bdf, ivhd_device->header.flags, iommu);
+ add_ivrs_mapping_entry(bdf, bdf, select->header.data_setting, iommu);
- return sizeof(struct acpi_ivhd_device_header);
+ return sizeof(*select);
}
static u16 __init parse_ivhd_device_range(
- union acpi_ivhd_device *ivhd_device,
+ const struct acpi_ivhd_device_range *range,
u16 header_length, u16 block_length, struct amd_iommu *iommu)
{
u16 dev_length, first_bdf, last_bdf, bdf;
- dev_length = sizeof(struct acpi_ivhd_device_range);
+ dev_length = sizeof(*range);
if ( header_length < (block_length + dev_length) )
{
AMD_IOMMU_DEBUG("IVHD Error: Invalid Device_Entry Length!\n");
return 0;
}
- if ( ivhd_device->range.trailer.type !=
- AMD_IOMMU_ACPI_IVHD_DEV_RANGE_END )
+ if ( range->end.header.type != ACPI_IVRS_TYPE_END )
{
AMD_IOMMU_DEBUG("IVHD Error: "
"Invalid Range: End_Type 0x%x\n",
- ivhd_device->range.trailer.type);
+ range->end.header.type);
return 0;
}
- first_bdf = ivhd_device->header.dev_id;
+ first_bdf = range->start.header.id;
if ( first_bdf >= ivrs_bdf_entries )
{
AMD_IOMMU_DEBUG("IVHD Error: "
return 0;
}
- last_bdf = ivhd_device->range.trailer.dev_id;
+ last_bdf = range->end.header.id;
if ( (last_bdf >= ivrs_bdf_entries) || (last_bdf <= first_bdf) )
{
AMD_IOMMU_DEBUG("IVHD Error: "
AMD_IOMMU_DEBUG(" Dev_Id Range: 0x%x -> 0x%x\n", first_bdf, last_bdf);
for ( bdf = first_bdf; bdf <= last_bdf; bdf++ )
- add_ivrs_mapping_entry(bdf, bdf, ivhd_device->header.flags, iommu);
+ add_ivrs_mapping_entry(bdf, bdf, range->start.header.data_setting,
+ iommu);
return dev_length;
}
static u16 __init parse_ivhd_device_alias(
- union acpi_ivhd_device *ivhd_device,
+ const struct acpi_ivrs_device8a *alias,
u16 header_length, u16 block_length, struct amd_iommu *iommu)
{
u16 dev_length, alias_id, bdf;
- dev_length = sizeof(struct acpi_ivhd_device_alias);
+ dev_length = sizeof(*alias);
if ( header_length < (block_length + dev_length) )
{
AMD_IOMMU_DEBUG("IVHD Error: Invalid Device_Entry Length!\n");
return 0;
}
- bdf = ivhd_device->header.dev_id;
+ bdf = alias->header.id;
if ( bdf >= ivrs_bdf_entries )
{
AMD_IOMMU_DEBUG("IVHD Error: Invalid Device_Entry Dev_Id 0x%x\n", bdf);
return 0;
}
- alias_id = ivhd_device->alias.dev_id;
+ alias_id = alias->used_id;
if ( alias_id >= ivrs_bdf_entries )
{
AMD_IOMMU_DEBUG("IVHD Error: Invalid Alias Dev_Id 0x%x\n", alias_id);
AMD_IOMMU_DEBUG(" Dev_Id Alias: 0x%x\n", alias_id);
- add_ivrs_mapping_entry(bdf, alias_id, ivhd_device->header.flags, iommu);
+ add_ivrs_mapping_entry(bdf, alias_id, alias->header.data_setting, iommu);
return dev_length;
}
static u16 __init parse_ivhd_device_alias_range(
- union acpi_ivhd_device *ivhd_device,
+ const struct acpi_ivhd_device_alias_range *range,
u16 header_length, u16 block_length, struct amd_iommu *iommu)
{
u16 dev_length, first_bdf, last_bdf, alias_id, bdf;
- dev_length = sizeof(struct acpi_ivhd_device_alias_range);
+ dev_length = sizeof(*range);
if ( header_length < (block_length + dev_length) )
{
AMD_IOMMU_DEBUG("IVHD Error: Invalid Device_Entry Length!\n");
return 0;
}
- if ( ivhd_device->alias_range.trailer.type !=
- AMD_IOMMU_ACPI_IVHD_DEV_RANGE_END )
+ if ( range->end.header.type != ACPI_IVRS_TYPE_END )
{
AMD_IOMMU_DEBUG("IVHD Error: "
"Invalid Range: End_Type 0x%x\n",
- ivhd_device->alias_range.trailer.type);
+ range->end.header.type);
return 0;
}
- first_bdf = ivhd_device->header.dev_id;
+ first_bdf = range->alias.header.id;
if ( first_bdf >= ivrs_bdf_entries )
{
AMD_IOMMU_DEBUG("IVHD Error: "
return 0;
}
- last_bdf = ivhd_device->alias_range.trailer.dev_id;
+ last_bdf = range->end.header.id;
if ( last_bdf >= ivrs_bdf_entries || last_bdf <= first_bdf )
{
AMD_IOMMU_DEBUG(
return 0;
}
- alias_id = ivhd_device->alias_range.alias.dev_id;
+ alias_id = range->alias.used_id;
if ( alias_id >= ivrs_bdf_entries )
{
AMD_IOMMU_DEBUG("IVHD Error: Invalid Alias Dev_Id 0x%x\n", alias_id);
AMD_IOMMU_DEBUG(" Dev_Id Alias: 0x%x\n", alias_id);
for ( bdf = first_bdf; bdf <= last_bdf; bdf++ )
- add_ivrs_mapping_entry(bdf, alias_id, ivhd_device->header.flags, iommu);
+ add_ivrs_mapping_entry(bdf, alias_id, range->alias.header.data_setting,
+ iommu);
return dev_length;
}
static u16 __init parse_ivhd_device_extended(
- union acpi_ivhd_device *ivhd_device,
+ const struct acpi_ivrs_device8b *ext,
u16 header_length, u16 block_length, struct amd_iommu *iommu)
{
u16 dev_length, bdf;
- dev_length = sizeof(struct acpi_ivhd_device_extended);
+ dev_length = sizeof(*ext);
if ( header_length < (block_length + dev_length) )
{
AMD_IOMMU_DEBUG("IVHD Error: Invalid Device_Entry Length!\n");
return 0;
}
- bdf = ivhd_device->header.dev_id;
+ bdf = ext->header.id;
if ( bdf >= ivrs_bdf_entries )
{
AMD_IOMMU_DEBUG("IVHD Error: Invalid Device_Entry Dev_Id 0x%x\n", bdf);
return 0;
}
- add_ivrs_mapping_entry(bdf, bdf, ivhd_device->header.flags, iommu);
+ add_ivrs_mapping_entry(bdf, bdf, ext->header.data_setting, iommu);
return dev_length;
}
static u16 __init parse_ivhd_device_extended_range(
- union acpi_ivhd_device *ivhd_device,
+ const struct acpi_ivhd_device_extended_range *range,
u16 header_length, u16 block_length, struct amd_iommu *iommu)
{
u16 dev_length, first_bdf, last_bdf, bdf;
- dev_length = sizeof(struct acpi_ivhd_device_extended_range);
+ dev_length = sizeof(*range);
if ( header_length < (block_length + dev_length) )
{
AMD_IOMMU_DEBUG("IVHD Error: Invalid Device_Entry Length!\n");
return 0;
}
- if ( ivhd_device->extended_range.trailer.type !=
- AMD_IOMMU_ACPI_IVHD_DEV_RANGE_END )
+ if ( range->end.header.type != ACPI_IVRS_TYPE_END )
{
AMD_IOMMU_DEBUG("IVHD Error: "
"Invalid Range: End_Type 0x%x\n",
- ivhd_device->extended_range.trailer.type);
+ range->end.header.type);
return 0;
}
- first_bdf = ivhd_device->header.dev_id;
+ first_bdf = range->extended.header.id;
if ( first_bdf >= ivrs_bdf_entries )
{
AMD_IOMMU_DEBUG("IVHD Error: "
return 0;
}
- last_bdf = ivhd_device->extended_range.trailer.dev_id;
+ last_bdf = range->end.header.id;
if ( (last_bdf >= ivrs_bdf_entries) || (last_bdf <= first_bdf) )
{
AMD_IOMMU_DEBUG("IVHD Error: "
first_bdf, last_bdf);
for ( bdf = first_bdf; bdf <= last_bdf; bdf++ )
- add_ivrs_mapping_entry(bdf, bdf, ivhd_device->header.flags, iommu);
+ add_ivrs_mapping_entry(bdf, bdf, range->extended.header.data_setting,
+ iommu);
return dev_length;
}
static u16 __init parse_ivhd_device_special(
- union acpi_ivhd_device *ivhd_device, u16 seg,
+ const struct acpi_ivrs_device8c *special, u16 seg,
u16 header_length, u16 block_length, struct amd_iommu *iommu)
{
u16 dev_length, bdf;
- dev_length = sizeof(struct acpi_ivhd_device_special);
+ dev_length = sizeof(*special);
if ( header_length < (block_length + dev_length) )
{
AMD_IOMMU_DEBUG("IVHD Error: Invalid Device_Entry Length!\n");
return 0;
}
- bdf = ivhd_device->special.dev_id;
+ bdf = special->used_id;
if ( bdf >= ivrs_bdf_entries )
{
AMD_IOMMU_DEBUG("IVHD Error: Invalid Device_Entry Dev_Id 0x%x\n", bdf);
return 0;
}
- add_ivrs_mapping_entry(bdf, bdf, ivhd_device->header.flags, iommu);
+ add_ivrs_mapping_entry(bdf, bdf, special->header.data_setting, iommu);
/* set device id of ioapic */
- ioapic_sbdf[ivhd_device->special.handle].bdf = bdf;
- ioapic_sbdf[ivhd_device->special.handle].seg = seg;
+ ioapic_sbdf[special->handle].bdf = bdf;
+ ioapic_sbdf[special->handle].seg = seg;
return dev_length;
}
-static int __init parse_ivhd_block(struct acpi_ivhd_block_header *ivhd_block)
+static int __init parse_ivhd_block(const struct acpi_ivrs_hardware *ivhd_block)
{
- union acpi_ivhd_device *ivhd_device;
+ const union acpi_ivhd_device *ivhd_device;
u16 block_length, dev_length;
struct amd_iommu *iommu;
- if ( ivhd_block->header.length <
- sizeof(struct acpi_ivhd_block_header) )
+ if ( ivhd_block->header.length < sizeof(*ivhd_block) )
{
AMD_IOMMU_DEBUG("IVHD Error: Invalid Block Length!\n");
return -ENODEV;
}
- iommu = find_iommu_from_bdf_cap(ivhd_block->header.dev_id,
- ivhd_block->cap_offset);
+ iommu = find_iommu_from_bdf_cap(ivhd_block->header.device_id,
+ ivhd_block->capability_offset);
if ( !iommu )
{
AMD_IOMMU_DEBUG("IVHD Error: No IOMMU for Dev_Id 0x%x Cap 0x%x\n",
- ivhd_block->header.dev_id, ivhd_block->cap_offset);
+ ivhd_block->header.device_id,
+ ivhd_block->capability_offset);
return -ENODEV;
}
/* parse Device Entries */
- block_length = sizeof(struct acpi_ivhd_block_header);
+ block_length = sizeof(*ivhd_block);
while ( ivhd_block->header.length >=
- (block_length + sizeof(struct acpi_ivhd_device_header)) )
+ (block_length + sizeof(struct acpi_ivrs_de_header)) )
{
- ivhd_device = (union acpi_ivhd_device *)
- ((u8 *)ivhd_block + block_length);
+ ivhd_device = (const void *)((const u8 *)ivhd_block + block_length);
AMD_IOMMU_DEBUG( "IVHD Device Entry:\n");
AMD_IOMMU_DEBUG( " Type 0x%x\n", ivhd_device->header.type);
- AMD_IOMMU_DEBUG( " Dev_Id 0x%x\n", ivhd_device->header.dev_id);
- AMD_IOMMU_DEBUG( " Flags 0x%x\n", ivhd_device->header.flags);
+ AMD_IOMMU_DEBUG( " Dev_Id 0x%x\n", ivhd_device->header.id);
+ AMD_IOMMU_DEBUG( " Flags 0x%x\n", ivhd_device->header.data_setting);
switch ( ivhd_device->header.type )
{
- case AMD_IOMMU_ACPI_IVHD_DEV_U32_PAD:
+ case ACPI_IVRS_TYPE_PAD4:
dev_length = parse_ivhd_device_padding(
sizeof(u32),
ivhd_block->header.length, block_length);
break;
- case AMD_IOMMU_ACPI_IVHD_DEV_U64_PAD:
+ case ACPI_IVRS_TYPE_PAD8:
dev_length = parse_ivhd_device_padding(
sizeof(u64),
ivhd_block->header.length, block_length);
break;
- case AMD_IOMMU_ACPI_IVHD_DEV_SELECT:
- dev_length = parse_ivhd_device_select(ivhd_device, iommu);
+ case ACPI_IVRS_TYPE_SELECT:
+ dev_length = parse_ivhd_device_select(&ivhd_device->select, iommu);
break;
- case AMD_IOMMU_ACPI_IVHD_DEV_RANGE_START:
+ case ACPI_IVRS_TYPE_START:
dev_length = parse_ivhd_device_range(
- ivhd_device,
+ &ivhd_device->range,
ivhd_block->header.length, block_length, iommu);
break;
- case AMD_IOMMU_ACPI_IVHD_DEV_ALIAS_SELECT:
+ case ACPI_IVRS_TYPE_ALIAS_SELECT:
dev_length = parse_ivhd_device_alias(
- ivhd_device,
+ &ivhd_device->alias,
ivhd_block->header.length, block_length, iommu);
break;
- case AMD_IOMMU_ACPI_IVHD_DEV_ALIAS_RANGE:
+ case ACPI_IVRS_TYPE_ALIAS_START:
dev_length = parse_ivhd_device_alias_range(
- ivhd_device,
+ &ivhd_device->alias_range,
ivhd_block->header.length, block_length, iommu);
break;
- case AMD_IOMMU_ACPI_IVHD_DEV_EXT_SELECT:
+ case ACPI_IVRS_TYPE_EXT_SELECT:
dev_length = parse_ivhd_device_extended(
- ivhd_device,
+ &ivhd_device->extended,
ivhd_block->header.length, block_length, iommu);
break;
- case AMD_IOMMU_ACPI_IVHD_DEV_EXT_RANGE:
+ case ACPI_IVRS_TYPE_EXT_START:
dev_length = parse_ivhd_device_extended_range(
- ivhd_device,
+ &ivhd_device->extended_range,
ivhd_block->header.length, block_length, iommu);
break;
- case AMD_IOMMU_ACPI_IVHD_DEV_SPECIAL:
+ case ACPI_IVRS_TYPE_SPECIAL:
dev_length = parse_ivhd_device_special(
- ivhd_device, ivhd_block->pci_segment,
+ &ivhd_device->special, ivhd_block->pci_segment_group,
ivhd_block->header.length, block_length, iommu);
break;
default:
return 0;
}
-static int __init parse_ivrs_block(struct acpi_ivrs_block_header *ivrs_block)
+static int __init parse_ivrs_block(const struct acpi_ivrs_header *ivrs_block)
{
- struct acpi_ivhd_block_header *ivhd_block;
- struct acpi_ivmd_block_header *ivmd_block;
+ const struct acpi_ivrs_hardware *ivhd_block;
+ const struct acpi_ivrs_memory *ivmd_block;
switch ( ivrs_block->type )
{
- case AMD_IOMMU_ACPI_IVHD_TYPE:
- ivhd_block = (struct acpi_ivhd_block_header *)ivrs_block;
+ case ACPI_IVRS_TYPE_HARDWARE:
+ ivhd_block = container_of(ivrs_block, const struct acpi_ivrs_hardware,
+ header);
return parse_ivhd_block(ivhd_block);
- case AMD_IOMMU_ACPI_IVMD_ALL_TYPE:
- case AMD_IOMMU_ACPI_IVMD_ONE_TYPE:
- case AMD_IOMMU_ACPI_IVMD_RANGE_TYPE:
- case AMD_IOMMU_ACPI_IVMD_IOMMU_TYPE:
- ivmd_block = (struct acpi_ivmd_block_header *)ivrs_block;
+ case ACPI_IVRS_TYPE_MEMORY_ALL:
+ case ACPI_IVRS_TYPE_MEMORY_ONE:
+ case ACPI_IVRS_TYPE_MEMORY_RANGE:
+ case ACPI_IVRS_TYPE_MEMORY_IOMMU:
+ ivmd_block = container_of(ivrs_block, const struct acpi_ivrs_memory,
+ header);
return parse_ivmd_block(ivmd_block);
default:
}
-static int __init parse_ivrs_table(struct acpi_table_header *_table)
+static int __init parse_ivrs_table(struct acpi_table_header *table)
{
- struct acpi_ivrs_block_header *ivrs_block;
+ const struct acpi_ivrs_header *ivrs_block;
unsigned long length;
int error = 0;
- struct acpi_table_header *table = (struct acpi_table_header *)_table;
BUG_ON(!table);
dump_acpi_table_header(table);
/* parse IVRS blocks */
- length = sizeof(struct acpi_ivrs_table_header);
+ length = sizeof(struct acpi_table_ivrs);
while ( (error == 0) && (table->length > (length + sizeof(*ivrs_block))) )
{
- ivrs_block = (struct acpi_ivrs_block_header *)
- ((u8 *)table + length);
+ ivrs_block = (struct acpi_ivrs_header *)((u8 *)table + length);
AMD_IOMMU_DEBUG("IVRS Block:\n");
AMD_IOMMU_DEBUG(" Type 0x%x\n", ivrs_block->type);
AMD_IOMMU_DEBUG(" Flags 0x%x\n", ivrs_block->flags);
AMD_IOMMU_DEBUG(" Length 0x%x\n", ivrs_block->length);
- AMD_IOMMU_DEBUG(" Dev_Id 0x%x\n", ivrs_block->dev_id);
+ AMD_IOMMU_DEBUG(" Dev_Id 0x%x\n", ivrs_block->device_id);
if ( table->length < (length + ivrs_block->length) )
{
return error;
}
-static int __init detect_iommu_acpi(struct acpi_table_header *_table)
+static int __init detect_iommu_acpi(struct acpi_table_header *table)
{
- struct acpi_ivrs_block_header *ivrs_block;
- struct acpi_table_header *table = (struct acpi_table_header *)_table;
+ const struct acpi_ivrs_header *ivrs_block;
unsigned long i;
- unsigned long length = sizeof(struct acpi_ivrs_table_header);
+ unsigned long length = sizeof(struct acpi_table_ivrs);
u8 checksum, *raw_table;
/* validate checksum: sum of entire table == 0 */
while ( table->length > (length + sizeof(*ivrs_block)) )
{
- ivrs_block = (struct acpi_ivrs_block_header *) ((u8 *)table + length);
+ ivrs_block = (struct acpi_ivrs_header *)((u8 *)table + length);
if ( table->length < (length + ivrs_block->length) )
return -ENODEV;
- if ( ivrs_block->type == AMD_IOMMU_ACPI_IVHD_TYPE )
- if ( amd_iommu_detect_one_acpi((void*)ivrs_block) != 0 )
- return -ENODEV;
+ if ( ivrs_block->type == ACPI_IVRS_TYPE_HARDWARE &&
+ amd_iommu_detect_one_acpi(
+ container_of(ivrs_block, const struct acpi_ivrs_hardware,
+ header)) != 0 )
+ return -ENODEV;
length += ivrs_block->length;
}
return 0;
last_bdf = (x); \
} while(0);
-static int __init get_last_bdf_ivhd(void *ivhd)
+static int __init get_last_bdf_ivhd(
+ const struct acpi_ivrs_hardware *ivhd_block)
{
- union acpi_ivhd_device *ivhd_device;
+ const union acpi_ivhd_device *ivhd_device;
u16 block_length, dev_length;
- struct acpi_ivhd_block_header *ivhd_block;
- ivhd_block = (struct acpi_ivhd_block_header *)ivhd;
-
- if ( ivhd_block->header.length <
- sizeof(struct acpi_ivhd_block_header) )
+ if ( ivhd_block->header.length < sizeof(*ivhd_block) )
{
AMD_IOMMU_DEBUG("IVHD Error: Invalid Block Length!\n");
return -ENODEV;
}
- block_length = sizeof(struct acpi_ivhd_block_header);
+ block_length = sizeof(*ivhd_block);
while ( ivhd_block->header.length >=
- (block_length + sizeof(struct acpi_ivhd_device_header)) )
+ (block_length + sizeof(struct acpi_ivrs_de_header)) )
{
- ivhd_device = (union acpi_ivhd_device *)
- ((u8 *)ivhd_block + block_length);
+ ivhd_device = (const void *)((u8 *)ivhd_block + block_length);
switch ( ivhd_device->header.type )
{
- case AMD_IOMMU_ACPI_IVHD_DEV_U32_PAD:
+ case ACPI_IVRS_TYPE_PAD4:
dev_length = sizeof(u32);
break;
- case AMD_IOMMU_ACPI_IVHD_DEV_U64_PAD:
+ case ACPI_IVRS_TYPE_PAD8:
dev_length = sizeof(u64);
break;
- case AMD_IOMMU_ACPI_IVHD_DEV_SELECT:
- UPDATE_LAST_BDF(ivhd_device->header.dev_id);
- dev_length = sizeof(struct acpi_ivhd_device_header);
+ case ACPI_IVRS_TYPE_SELECT:
+ UPDATE_LAST_BDF(ivhd_device->select.header.id);
+ dev_length = sizeof(ivhd_device->header);
break;
- case AMD_IOMMU_ACPI_IVHD_DEV_ALIAS_SELECT:
- UPDATE_LAST_BDF(ivhd_device->header.dev_id);
- dev_length = sizeof(struct acpi_ivhd_device_alias);
+ case ACPI_IVRS_TYPE_ALIAS_SELECT:
+ UPDATE_LAST_BDF(ivhd_device->alias.header.id);
+ dev_length = sizeof(ivhd_device->alias);
break;
- case AMD_IOMMU_ACPI_IVHD_DEV_EXT_SELECT:
- UPDATE_LAST_BDF(ivhd_device->header.dev_id);
- dev_length = sizeof(struct acpi_ivhd_device_extended);
+ case ACPI_IVRS_TYPE_EXT_SELECT:
+ UPDATE_LAST_BDF(ivhd_device->extended.header.id);
+ dev_length = sizeof(ivhd_device->extended);
break;
- case AMD_IOMMU_ACPI_IVHD_DEV_RANGE_START:
- UPDATE_LAST_BDF(ivhd_device->range.trailer.dev_id);
- dev_length = sizeof(struct acpi_ivhd_device_range);
+ case ACPI_IVRS_TYPE_START:
+ UPDATE_LAST_BDF(ivhd_device->range.end.header.id);
+ dev_length = sizeof(ivhd_device->range);
break;
- case AMD_IOMMU_ACPI_IVHD_DEV_ALIAS_RANGE:
- UPDATE_LAST_BDF(ivhd_device->alias_range.trailer.dev_id)
- dev_length = sizeof(struct acpi_ivhd_device_alias_range);
+ case ACPI_IVRS_TYPE_ALIAS_START:
+ UPDATE_LAST_BDF(ivhd_device->alias_range.end.header.id)
+ dev_length = sizeof(ivhd_device->alias_range);
break;
- case AMD_IOMMU_ACPI_IVHD_DEV_EXT_RANGE:
- UPDATE_LAST_BDF(ivhd_device->extended_range.trailer.dev_id)
- dev_length = sizeof(struct acpi_ivhd_device_extended_range);
+ case ACPI_IVRS_TYPE_EXT_START:
+ UPDATE_LAST_BDF(ivhd_device->extended_range.end.header.id)
+ dev_length = sizeof(ivhd_device->extended_range);
break;
- case AMD_IOMMU_ACPI_IVHD_DEV_SPECIAL:
- UPDATE_LAST_BDF(ivhd_device->special.dev_id)
- dev_length = sizeof(struct acpi_ivhd_device_special);
+ case ACPI_IVRS_TYPE_SPECIAL:
+ UPDATE_LAST_BDF(ivhd_device->special.used_id)
+ dev_length = sizeof(ivhd_device->special);
break;
default:
AMD_IOMMU_DEBUG("IVHD Error: Invalid Device Type!\n");
return 0;
}
-static int __init get_last_bdf_acpi(struct acpi_table_header *_table)
+static int __init get_last_bdf_acpi(struct acpi_table_header *table)
{
- struct acpi_ivrs_block_header *ivrs_block;
- struct acpi_table_header *table = (struct acpi_table_header *)_table;
- unsigned long length = sizeof(struct acpi_ivrs_table_header);
+ const struct acpi_ivrs_header *ivrs_block;
+ unsigned long length = sizeof(struct acpi_table_ivrs);
while ( table->length > (length + sizeof(*ivrs_block)) )
{
- ivrs_block = (struct acpi_ivrs_block_header *) ((u8 *)table + length);
+ ivrs_block = (struct acpi_ivrs_header *)((u8 *)table + length);
if ( table->length < (length + ivrs_block->length) )
return -ENODEV;
- if ( ivrs_block->type == AMD_IOMMU_ACPI_IVHD_TYPE )
- if ( get_last_bdf_ivhd((void*)ivrs_block) != 0 )
- return -ENODEV;
+ if ( ivrs_block->type == ACPI_IVRS_TYPE_HARDWARE &&
+ get_last_bdf_ivhd(
+ container_of(ivrs_block, const struct acpi_ivrs_hardware,
+ header)) != 0 )
+ return -ENODEV;
length += ivrs_block->length;
}
return 0;
int __init amd_iommu_detect_acpi(void)
{
- return acpi_table_parse(AMD_IOMMU_ACPI_IVRS_SIG, detect_iommu_acpi);
+ return acpi_table_parse(ACPI_SIG_IVRS, detect_iommu_acpi);
}
int __init amd_iommu_get_ivrs_dev_entries(void)
{
- acpi_table_parse(AMD_IOMMU_ACPI_IVRS_SIG, get_last_bdf_acpi);
+ acpi_table_parse(ACPI_SIG_IVRS, get_last_bdf_acpi);
return last_bdf + 1;
}
int __init amd_iommu_update_ivrs_mapping_acpi(void)
{
- return acpi_table_parse(AMD_IOMMU_ACPI_IVRS_SIG, parse_ivrs_table);
+ return acpi_table_parse(ACPI_SIG_IVRS, parse_ivrs_table);
}